package io.modifier.basic.core.data.hand

sealed interface HandError

typealias RootError = HandError

sealed interface DataError : HandError {
    enum class NetWorkError : DataError {
        NO_INTERNET,
        TOO_MANY_REQUESTS,
        UNEXPECTED_TOKEN,
        PAYLOAD,
        REQUEST_TIMEOUT
    }

    enum class LocalError : DataError {
        SERIALIZATION,
        UNKNOWN
    }
}

sealed interface XxxUseCaseError : HandError {
    enum class FinalError : XxxUseCaseError {
        ABC_ERROR,
        CHUNK_ERROR
    }
}

sealed interface HandResult<out D, out E : RootError> {
    data class Success<out D, out E : RootError>(val data: D) : HandResult<D, E>
    data class Error<out D, out E : RootError>(val error: E) : HandResult<D, E>
}

inline fun <D, E : RootError, R> HandResult<D, E>.andThen(block: D.() -> HandResult<R, E>): HandResult<R, E> {
    return when (this) {
        is HandResult.Error -> {
            HandResult.Error(this.error)
        }

        is HandResult.Success -> {
            block(this.data)
        }
    }
}

inline fun <D, E : RootError> HandResult<D, E>.onSuccess(action: (value: D) -> Unit): HandResult<D, E> {
    if (this is HandResult.Success) {
        action(this.data)
    }
    return this
}

inline fun <D, E : RootError> HandResult<D, E>.onFailure(action: (error: E) -> Unit): HandResult<D, E> {
    if (this is HandResult.Error) {
        action(this.error)
    }
    return this
}

fun HandResult<*, DataError>.asUnitText() {
    if (this is HandResult.Error) {
        when (this.error) {
            DataError.LocalError.SERIALIZATION -> "Ooops, There is some error when serializing the data!"
            DataError.LocalError.UNKNOWN -> TODO()
            DataError.NetWorkError.NO_INTERNET -> TODO()
            DataError.NetWorkError.TOO_MANY_REQUESTS -> TODO()
            DataError.NetWorkError.UNEXPECTED_TOKEN -> TODO()
            DataError.NetWorkError.PAYLOAD -> TODO()
            DataError.NetWorkError.REQUEST_TIMEOUT -> TODO()
        }
    } else {
        throw Exception()
    }
}







